﻿using System;
using System.Globalization;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;

namespace Gmantis.Controls
{
    public enum TabItemShape
    {
        Rectangle,
        Rounded,
        Sloped,
        Ribbon
    }

    [TemplateVisualState(Name = "BottomTabStripPlacement", GroupName = "TabStripPlacementStates"), 
    TemplateVisualState(Name = "RightTabStripPlacement", GroupName = "TabStripPlacementStates"), 
    TemplateVisualState(Name = "Normal", GroupName = "CommonStates"), 
    TemplateVisualState(Name = "MouseOver", GroupName = "CommonStates"), 
    TemplateVisualState(Name = "Disabled", GroupName = "CommonStates"), 
    TemplateVisualState(Name = "Unselected", GroupName = "SelectionStates"), 
    TemplateVisualState(Name = "TopTabStripPlacement", GroupName = "TabStripPlacementStates"), 
    TemplateVisualState(Name = "Selected", GroupName = "SelectionStates"), 
    TemplateVisualState(Name = "LeftTabStripPlacement", GroupName = "TabStripPlacementStates")]
    public class TabItemPresenter : ContentControl
    {
        // Fields
        internal bool _isLoaded;
        private bool _throwIsMouseOverChanged;
        public static readonly DependencyProperty CornerRadiusProperty = DependencyProperty.Register("CornerRadius", typeof(double), typeof(TabItemPresenter), new PropertyMetadata(15.0));
        internal static readonly DependencyProperty ForceMouseOverProperty = DependencyProperty.Register("ForceMouseOver", typeof(bool), typeof(TabItemPresenter), new PropertyMetadata(new PropertyChangedCallback(TabItemPresenter.OnForceMouseOverPropertyChanged)));
        public static readonly DependencyProperty IsMouseOverProperty = DependencyProperty.Register("IsMouseOver", typeof(bool), typeof(TabItemPresenter), new PropertyMetadata(new PropertyChangedCallback(TabItemPresenter.OnIsMouseOverPropertyChanged)));
        public static readonly DependencyProperty IsSelectedProperty = DependencyProperty.Register("IsSelected", typeof(bool), typeof(TabItemPresenter), new PropertyMetadata(new PropertyChangedCallback(TabItemPresenter.OnIsSelectedPropertyChanged)));
        public static readonly DependencyProperty MouseOverBrushProperty = DependencyProperty.Register("MouseOverBrush", typeof(Brush), typeof(TabItemPresenter), null);
        public static readonly DependencyProperty PressedBrushProperty = DependencyProperty.Register("PressedBrush", typeof(Brush), typeof(TabItemPresenter), null);
        public static readonly DependencyProperty SelectedBackgroundProperty = DependencyProperty.Register("SelectedBackground", typeof(Brush), typeof(TabItemPresenter), null);
        public static readonly DependencyProperty ShowSelectedCuesProperty = DependencyProperty.Register("ShowSelectedCues", typeof(bool), typeof(TabItemPresenter), new PropertyMetadata(true, new PropertyChangedCallback(TabItemPresenter.OnShowSelectedCuesPropertyChanged)));
        public static readonly DependencyProperty TabShapeProperty = DependencyProperty.Register("TabShape", typeof(TabItemShape), typeof(TabItemPresenter), null);
        public static readonly DependencyProperty TabStripPlacementProperty = DependencyProperty.Register("TabStripPlacement", typeof(Dock), typeof(TabItemPresenter), new PropertyMetadata(Dock.Top, new PropertyChangedCallback(TabItemPresenter.OnTabStripPlacementPropertyChanged)));

        // Events
        public event EventHandler<PropertyChangedEventArgs<bool>> IsMouseOverChanged;

        // Methods
        public TabItemPresenter()
        {
            RoutedEventHandler handler = null;
            DependencyPropertyChangedEventHandler handler2 = null;
            this._throwIsMouseOverChanged = true;
            base.DefaultStyleKey = typeof(TabItemPresenter);
            if (handler == null)
            {
                handler = delegate(object param0, RoutedEventArgs param1)
                {
                    this.ChangeVisualStateSelection(false);
                    this.ChangeVisualStateTabStripPlacement(false);
                    this.ChangeVisualStateCommon(false);
                };
            }
            base.Loaded += handler;
            if (handler2 == null)
            {
                handler2 = (s, a) => this.ChangeVisualStateCommon(true);
            }
            base.IsEnabledChanged += handler2;
            base.MouseEnter += new MouseEventHandler(this.Control_MouseEnter);
            base.MouseLeave += new MouseEventHandler(this.Control_MouseLeave);
        }

        private void Control_MouseEnter(object sender, MouseEventArgs e)
        {
            if (InputEventArgs.GetPointerType(e) == PointerDeviceType.Mouse)
            {
                this.IsMouseOver = true;
            }
        }

        private void Control_MouseLeave(object sender, MouseEventArgs e)
        {
            if (InputEventArgs.GetPointerType(e) == PointerDeviceType.Mouse)
            {
                this.IsMouseOver = false;
            }
        }

        protected void ChangeVisualStateCommon(bool useTransitions)
        {
            if (!base.IsEnabled)
            {
                VisualStateHelper.GoToState(this, "Disabled", useTransitions);
            }
            if (base.IsEnabled)
            {
                VisualStateHelper.GoToState(this, "MouseOver", useTransitions);
            }
            if ((base.IsEnabled && !this.IsMouseOver) && !this.ForceMouseOver)
            {
                VisualStateHelper.GoToState(this, "Normal", useTransitions);
            }
        }

        protected void ChangeVisualStateSelection(bool useTransitions)
        {
            VisualStateHelper.GoToState(this, "Unselected", useTransitions);
            if (this.IsSelected && this.ShowSelectedCues)
            {
                VisualStateHelper.GoToState(this, "Selected", useTransitions);
            }
        }

        protected void ChangeVisualStateTabStripPlacement(bool useTransitions)
        {
            if (this.TabStripPlacement == Dock.Right)
            {
                VisualStateHelper.GoToState(this, "RightTabStripPlacement", useTransitions);
            }
            if (this.TabStripPlacement == Dock.Bottom)
            {
                VisualStateHelper.GoToState(this, "BottomTabStripPlacement", useTransitions);
            }
            if (this.TabStripPlacement == Dock.Left)
            {
                VisualStateHelper.GoToState(this, "LeftTabStripPlacement", useTransitions);
            }
            if (this.TabStripPlacement == Dock.Top)
            {
                VisualStateHelper.GoToState(this, "TopTabStripPlacement", useTransitions);
            }
        }

        public override void OnApplyTemplate()
        {
            string str = string.Empty;
            base.OnApplyTemplate();
            this._isLoaded = true;
            if (!string.IsNullOrEmpty(str))
            {
                this._isLoaded = false;
                if ((base.Template != null) && !PlatformIndependent.IsInDesignMode(this))
                {
                    throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "Template cannot be applied to TabItemPresenter.\nDetails: {0}", new object[] { str }));
                }
            }
            else
            {
                this.ChangeVisualStateSelection(false);
                this.ChangeVisualStateTabStripPlacement(false);
                this.ChangeVisualStateCommon(false);
            }
        }

        private static void OnForceMouseOverPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            (d as TabItemPresenter).ChangeVisualStateCommon(true);
        }

        private static void OnIsMouseOverPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            TabItemPresenter sender = d as TabItemPresenter;
            if ((sender.IsMouseOverChanged != null) && sender._throwIsMouseOverChanged)
            {
                PropertyChangedEventArgs<bool> args = new PropertyChangedEventArgs<bool>
                {
                    OldValue = (bool)e.OldValue,
                    NewValue = (bool)e.NewValue
                };
                sender.IsMouseOverChanged(sender, args);
            }
            sender.ChangeVisualStateCommon(true);
        }

        private static void OnIsSelectedPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            (d as TabItemPresenter).ChangeVisualStateSelection(true);
        }

        private static void OnShowSelectedCuesPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            (d as TabItemPresenter).ChangeVisualStateSelection(true);
        }

        private static void OnTabStripPlacementPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            (d as TabItemPresenter).ChangeVisualStateTabStripPlacement(true);
        }

        // Properties
        public double CornerRadius
        {
            get { return (double)GetValue(CornerRadiusProperty); }
            set { SetValue(CornerRadiusProperty, value); }
        }

        internal bool ForceMouseOver
        {
            get { return (bool)GetValue(ForceMouseOverProperty); }
            set { SetValue(ForceMouseOverProperty, value); }
        }

        public bool IsMouseOver
        {
            get { return (bool)GetValue(IsMouseOverProperty); }
            internal set { SetValue(IsMouseOverProperty, value); }
        }

        public bool IsSelected
        {
            get { return (bool)GetValue(IsSelectedProperty); }
            set { SetValue(IsSelectedProperty, value); }
        }

        public Brush MouseOverBrush
        {
            get { return (Brush)GetValue(MouseOverBrushProperty); }
            set { SetValue(MouseOverBrushProperty, value); }
        }

        public Brush PressedBrush
        {
            get { return (Brush)GetValue(PressedBrushProperty); }
            set { SetValue(PressedBrushProperty, value); }
        }

        public Brush SelectedBackground
        {
            get { return (Brush)GetValue(SelectedBackgroundProperty); }
            set { SetValue(SelectedBackgroundProperty, value); }
        }

        public bool ShowSelectedCues
        {
            get { return (bool)GetValue(ShowSelectedCuesProperty); }
            set { SetValue(ShowSelectedCuesProperty, value); }
        }

        public TabItemShape TabShape
        {
            get { return (TabItemShape)GetValue(TabShapeProperty); }
            set { SetValue(TabShapeProperty, value); }
        }

        public Dock TabStripPlacement
        {
            get { return (Dock)GetValue(TabStripPlacementProperty); }
            set { SetValue(TabStripPlacementProperty, value); }
        }
    }
}
